#ifndef M8DEF_H_
#define M8DEF_H_

#define F_CPU 16000000

#include "types.h"
#include "kernel.h"

#ifndef TYPES_H_
  #error "Types not present."
#endif

#ifndef KERNEL_H_
  #error "Kernel not present."
#endif

#ifndef __IO_OFFSET
  #if __AVR_ARCH__ >= 100
    #define __IO_OFFSET 0x00
  #else
    #define __IO_OFFSET 0x20
  #endif
#endif

/* Bit Definitions */
#define bs(x) 1 << x
#define br(x) (~(1 << x))


/* Direct Port Access */
#define O(x) *(volatile BYTE *)(x)
#define I(x, bit) (x) & (bs(bit))

/* PORTB Definitions */
#define DDB (volatile BYTE *)(0x17 + __IO_OFFSET)
#define OB (volatile BYTE *)(0x18 + __IO_OFFSET)
#define IB *(volatile BYTE *)(0x16 + __IO_OFFSET)

/* PORTC Definitions */
#define DDC (volatile BYTE *)(0x14 + __IO_OFFSET)
#define OC (volatile BYTE *)(0x15 + __IO_OFFSET)
#define IC *(volatile BYTE *)(0x13 + __IO_OFFSET)

/* PORTD Definition */
#define DDD (volatile BYTE *)(0x11 + __IO_OFFSET)
#define OD (volatile BYTE *)(0x12 + __IO_OFFSET)
#define ID *(volatile BYTE *)(0x10 + __IO_OFFSET)


/* EEPROM Definition */
#define __EEDR__ (volatile BYTE *)(0x3D + __IO_OFFSET)
#define __EECR__ (volatile BYTE *)(0x1C + __IO_OFFSET)
#define __EEAR__ (volatile WORD *)(0x1F + __IO_OFFSET)

/* Timer Counter Interrpupt Mask */
#define __TIMSK__ (volatile BYTE *)(0x39 + __IO_OFFSET)

/* Timers Counter 0 */
#define __TCNT0__ (volatile BYTE *)(0x32 + __IO_OFFSET)
#define __TCCR0__ (volatile BYTE *)(0x33 + __IO_OFFSET)

/* Timers Counter 1 */
#define __TCNT1L__ (volatile BYTE *)(0x2C + __IO_OFFSET)
#define __TCNT1H__ (volatile BYTE *)(0x2D + __IO_OFFSET)
#define __TCCR1A__ (volatile BYTE *)(0x2F + __IO_OFFSET)
#define __TCCR1B__ (volatile BYTE *)(0x2E + __IO_OFFSET)

#define __TOIE0 0
#define __TOIE1 2
#define __OCIE1B 3
#define __OCIE1A 4
#define __TICIE1 5
#define __TOIE2 6
#define __OCIE2 7


/* MCU Control Register */
#define __MCUCR__ (volatile BYTE *)(0x34) + __IO_OFFSET
#define __SE 7
#define __SM2 6
#define __SM1 5
#define __SM0 4
#define __ISC11 3
#define __ISC10 2
#define __ISC01 1
#define __ISC00 0

/* Interrupt Vectors */
#define IRQ_RESET __vector_0
#define IRQ_INT0 __vector_1
#define IRQ_INT1 __vector_2
#define IRQ_TIMER2_COMP __vector_3
#define IRQ_TIMER2_OVF __vector_4
#define IRQ_TIMER1_CAPT __vector_5
#define IRQ_TIMER1_COMPA __vector_6
#define IRQ_TIMER1_COMPB __vector_7
#define IRQ_TIMER1_OVF __vector_8
#define IRQ_TIMER0_OVF __vector_9
#define IRQ_SPI_STC __vector_10
#define IRQ_USART_RXC __vector_11
#define IRQ_USART_UDRE __vector_12
#define IRQ_USART_TXC __vector_13
#define IRQ_ADC __vector_14
#define IRQ_EE_RDY __vector_15
#define IRQ_ANA_COMP __vector_16
#define IRQ_TWI __vector_17
#define IRQ_SPM_RDY __vector_18


/* GICR Global Interrupt Control Register */
#define __GICR__ (volatile BYTE *)(0x3B) + __IO_OFFSET

/* External Interrupt 0 */
#define __INT0 6

/* External Interrupt 1 */
#define __INT1 7

/* ADC Registers */
#define __ADMUX__ (volatile BYTE *)(0x07 + __IO_OFFSET)
#define __ADCSRA__ (volatile BYTE *)(0x06 + __IO_OFFSET)

/* ADC Data registers */
#define __ADCH__ (volatile BYTE *)(0x05 + __IO_OFFSET)
#define __ADCL__ (volatile BYTE *)(0x04 + __IO_OFFSET)

/* ADC Defs */
#define __REFS0 0x40
#define __REFS1 0x80
#define __ADLAR 0x20

#define __ADEN 0x80
#define __ADSC 0x40
#define __ADFR 0x20
#define __ADIF 0x10
#define __ADIE 0x08
#define __ADPS2 0x04
#define __ADPS1 0x02
#define __ADPS0 0x01

/* ADC Channels */
#define __ADCchannel(x) 0x0 ## x
#define __ADC0 0x00
#define __ADC1 0x01
#define __ADC2 0x02
#define __ADC3 0x03
#define __ADC4 0x04
#define __ADC5 0x05
#define __ADC6 0x06
#define __ADC7 0x07

/* ALU STAUTS */
#define __C 0
#define __Z 1
#define __N 2
#define __V 3
#define __S 4
#define __H 5
#define __T 6
#define __I 7

#define __SREG__ *(volatile BYTE *)(0x3F + __IO_OFFSET)
#define MATH_ERROR ((__SREG__) & (1 << __C) & (1 << __Z))
#define INTERRUPTS_ENABLE ((__SREG__) & (1 << __I))

/* Special Function IO Register */
#define __SFIOR__ (volatile BYTE *)(0x30 + __IO_OFFSET)

/* Analog Comparator Control and Status Register */
#define __ACSR__ (volatile BYTE *)(0x08 + __IO_OFFSET)

#endif /* M8DEF_H_ */
